package com.lzs.system.config;

import com.lzs.entity.Menu;
import com.lzs.entity.OperationLog;
import com.lzs.system.mapper.OperationLogMapper;
import com.lzs.system.service.MenuService;
import com.lzs.util.JwtUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;


@Aspect
@Component
public class AspectClassAnno {

    @Autowired
    private MenuService menuService;

    @Autowired
    private OperationLogMapper operationLogMapper;

    /**
     * 定义切入点，切入点为com.example.aop下的所有函数
     */
//    @Pointcut("execution(public * com.aaa.system.*.*(..))")
    @Pointcut("execution(* com.lzs.system.controller.*.insert*(..))")
    public void addLog() {
    }

    @Pointcut("execution(* com.lzs.system.controller.*.update*(..))")
    public void editLog() {

    }

    @Pointcut("execution(* com.lzs.system.controller.*.delete*(..))")
    public void deleteLog() {
    }

    @Pointcut("execution(* com.lzs.system.controller.*.reset*(..))")
    public void resetLog() {
    }

    /**
     * 保存添加操作的日志
     *
     * @param
     * @throws Throwable
     */
    @AfterReturning(returning = "joinPoint", pointcut = "addLog()")
    public void insertLog(JoinPoint joinPoint) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getHeader("token");
        Long userId = JwtUtils.getMemberIdByJwtToken(token);
        //全类名
        String className = joinPoint.getSignature().getDeclaringTypeName();
        //方法名
        String name = joinPoint.getSignature().getName();
        String logName = "";
//        String url = "/" + name.substring(14) + "/update";
        String url="/system/"+name.substring(14)+"/insertOrUpdate"+name.substring(14);
        Menu menu = menuService.findByUrl(url);
            if (StringUtils.isEmpty(menu)) {
            logName = url;
        } else {
            logName = menu.getName();
        }
        String method = name;
        OperationLog operationLog = new OperationLog(null, "业务日志", logName, userId, className, name, new Date(), "成功", null);
        int insert = operationLogMapper.insert(operationLog);

    }

    /**
     * 保存修改操作的日志
     *
     * @param
     * @throws Throwable
     */
    @AfterReturning(returning = "joinPoint", pointcut = "editLog()")
    public void updateLog(JoinPoint joinPoint) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getHeader("token");
        Long userId = JwtUtils.getMemberIdByJwtToken(token);
        String className = joinPoint.getSignature().getDeclaringTypeName();
        //方法名
        String name = joinPoint.getSignature().getName();
        String url = "";
        String logName = "";
        String method = name;
        if (name.indexOf("update")!=-1) {
            if (name.equals("updateUserStatus")) {
                logName = "更改账号状态";
            } else if (name.equals("updateUserRole")) {
                logName = "分配角色";
            } else if (name.equals("updateMenuByRoleId")) {
                logName = "分配菜单权限";
            }else if (name.equals("updateWarehouseByDeptId")){
                logName = "分配仓库";
            }
        } else {
//            url = "/" + name.substring(4) + "/edit";
//            Menu menu = menuService.findByUrl(url);
//            if (StringUtils.isEmpty(menu)) {
//                logName = url;
//            } else {
//                logName = menu.getName();
//            }
        }

        OperationLog operationLog = new OperationLog(null, "业务日志", logName, userId, className, name, new Date(), "成功", null);
        int insert = operationLogMapper.insert(operationLog);

    }

    /**
     * 保存删除操作的日志
     *
     * @param
     * @throws Throwable
     */
    @AfterReturning(returning = "joinPoint", pointcut = "deleteLog()")
    public void deleteLog(JoinPoint joinPoint) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getHeader("token");
        Long userId = JwtUtils.getMemberIdByJwtToken(token);
        String className = joinPoint.getSignature().getDeclaringTypeName();
        String name = joinPoint.getSignature().getName();

        String method = name;
        String url = "";
        String logName = "";

        if (name.equals("deleteLoginLog")) {
            logName = "清空登录日志";
        }
        if (name.equals("deleteOpera")) {
            logName = "清空业务日志";
        } else {
            url = "/system/" + name.substring(6) + "/delete"+name.substring(6);
            Menu menu = menuService.findByUrl(url);
            if (StringUtils.isEmpty(menu)) {
                logName = url;
            } else {
                logName = menu.getName();
            }

        }
        OperationLog operationLog = new OperationLog(null, "业务日志", logName, userId, className, name, new Date(), "成功", null);
        int insert = operationLogMapper.insert(operationLog);
    }

    /**
     * 后置通知，保存重置密码日志
     *
     * @param joinPoint
     * @throws Throwable
     */
    @AfterReturning(returning = "joinPoint", pointcut = "resetLog()")
    public void resetLog(JoinPoint joinPoint) throws Throwable {
        String className = joinPoint.getSignature().getDeclaringTypeName();
        String name = joinPoint.getSignature().getName();
        String logName = "重置密码";
        String method = name;
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getHeader("token");
        Long userId = JwtUtils.getMemberIdByJwtToken(token);
        OperationLog operationLog = new OperationLog(null, "业务日志", logName, userId, className, name, new Date(), "成功", null);
        int insert = operationLogMapper.insert(operationLog);
    }

    /**
     * 异常通知，保存异常日志
     *
     * @param joinPoint
     * @param throwable
     */
    @AfterThrowing(pointcut = "execution(* com.lzs.system.controller.*.*(..))", throwing = "throwable")
    public void exceptionLog(JoinPoint joinPoint, Throwable throwable) {
        String className = joinPoint.getSignature().getDeclaringTypeName();
        String name = joinPoint.getSignature().getName();
        String logName = "";
        String method = name;
        String message = throwable.getMessage();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getHeader("token");
        Long userId = JwtUtils.getMemberIdByJwtToken(token);
        OperationLog operationLog = new OperationLog(null, "异常日志", logName, userId, className, name, new Date(), "成功", message);
        int insert = operationLogMapper.insert(operationLog);
    }
}
